/***************************************************************************************
  *Copyright(C),2010-2016,Sumscope
  *FileName   : TableUser.cpp
  *Author     : scofined.qi
  *Version    : 1.0
  *Date       : 2016/06/02
  *Desc       : //用于说明此程序文件完成的主要功能
  *Relation   :
  *Other      : //其他内容说明
  *Function   : //主要函数列表，每条记录应包含函数名及功能简要说明
  *History    : //修改历史纪录列表，每条修改记录应包含修改日期，修改者以及修改内容简介
  ***************************************************************************************/
#include "TableUser.h"
#include "Table.h"
#include "TableSorter.h"
#include "skiplist.h"
#include "SortBuffer.h"
#include <core/container/SHash.h>

#ifdef WIN32
#define BASSERT assert
#else
#define BASSERT //
#endif

namespace qb{
	namespace ht{
#define PERF_CHECK
#ifdef PERF_CHECK
#define CHECKROWMAP CheckRowMap()
#else
#define CHECKROWMAP
#endif
		IntVec::IntVec(const char* jsonList)
		{
			// 抽取字符串中的所有数字
			//"[1,2,3,4,5,6]"
			int num = 0;
			int count = 0;
			int len = strlen(jsonList);
			for (int i = 0; i <= len; i++)
			{
				char c = i < len ? jsonList[i] : 0;
				if (c >= '0' && c <= '9')
				{
					count++;
					num = num * 10 + (c - '0');
				}
				else if (count > 0)
				{
					this->push_back(num);
					count = 0;
					num = 0;
				}
			}
		}
		void GridColumnSet::SetSelection(const IntVec& columns)
		{
			for (int i = 0; i < (int)columns.size(); i++)
			{
				m_select_columns.push_back((kColumn)columns.at(i));
			}
		}
		void GridColumnSet::SetVisible(const IntVec& columns)
		{
			for (int i = 0; i < (int)columns.size(); i++)
			{
				m_visible_columns.push_back((kColumn)columns.at(i));
			}
		}
		void GridColumnSet::SetMultiSort(const IntVec& columns)
		{
			for (int i = 0; i < (int)columns.size(); i++)
			{
				m_sort_columns.push_back((kColumn)columns.at(i));
			}
		}
		void GridColumnSet::SetSortDecFlags(const IntVec& columns)
		{
			for (int i = 0; i < (int)columns.size(); i++)
			{
				m_sort_desc_flags.push_back(columns.at(i) != 0);
			}
		}
		////////////////////////////////////////////////////////////////////////////////
		unsigned int TableUser::RecordKey::GetHash()const{
            return qb::base::GetFastHash(&rid, sizeof(rid), 0);
		}
        TableUser::TableUser(const GridColumnSet& columns, void* grid) :
			m_user_window(grid), m_grid_columns(columns),
			m_stateid(0), m_user_type(kTableUserTypeGrid),
			m_searcher(0), m_summary(0),
			m_table(0)
		{
			m_record_list = new SortedRecordList(new RecordComparator(this));
			m_record_list->SetCheckFlag(false);
			//m_record_list->SetDelegate(this);
		}

		TableUser::~TableUser()
		{
			if (m_record_list)
				delete m_record_list;
		}

		void TableUser::ClearSortColumns()
		{
			m_grid_columns.m_sort_columns.clear();
			m_grid_columns.m_sort_desc_flags.clear();
		}
		void TableUser::AddSortColumn(int column, bool ascend)
		{
			ColumnVec::iterator it = std::find(m_grid_columns.m_sort_columns.begin(), m_grid_columns.m_sort_columns.end(), column);
			if (it == m_grid_columns.m_sort_columns.end())
			{
				m_grid_columns.m_sort_columns.push_back((kColumn)column);
				m_grid_columns.m_sort_desc_flags.push_back(ascend);
			}
		}
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool TableUser::IsRecordNeeded(RecordId rid, const void* record, int size)
		{
			if (m_searcher && !m_searcher->IsRecordNeed(rid, record, size))
				return false;
			if (!m_filters.empty())
			{
				for (TableFilterVec::iterator it = m_filters.begin(); it != m_filters.end(); ++it)
				{
					TableFilter* filter = *it;
					if (!filter->IsRecordNeed(rid, record, size))
						return false;
				}
			}
			return true;
		}

		bool TableUser::IsSortColumnChanged(const BoolVec& fieldChangeFlags)
		{
			// 判断当前记录更新后产生的更新标志位中是否有拍序列
			// 只有当包含拍序列，才会引起插入排序，否则不会引起重新插入
			for (int i = 0; i < (int)m_grid_columns.m_sort_columns.size(); i++)
			{
				kColumn col = m_grid_columns.m_sort_columns.at(i);
                BASSERT(col < (int)fieldChangeFlags.size());
				if (fieldChangeFlags[col])
					return true;
			}
			return false;
		}

		int  TableUser::OnCompare(const RecordKey& k1, const RecordKey& k2)
		{
			return CompareRecord(m_table,
				m_table->ReadRecord(k1.rid, kRecordChannelCompareFirst),
				m_table->ReadRecord(k2.rid, kRecordChannelCompareLast)
				);
		}

        qb::ht::TableUser::KeyIterator TableUser::GetBegin()
		{
			return m_record_list->GetBegin();
		}

        qb::ht::TableUser::KeyIterator TableUser::GetEnd()
		{
			return m_record_list->GetEnd();
		}

		int TableUser::GetRecordCount() const
		{
			return m_record_list->GetCount();
		}

        void TableUser::GetKeys(int index, int count, std::vector<RecordKey>& keys)
		{
			m_record_list->GetKeys(index, count, keys);
		}

		bool TableUser::InsertRow(Table* table, RecordId rid, const void* record, int size,
			const BoolVec& fieldChangeFlags, bool newRecord)
		{
			// newRecord 为true，表示rid是新纪录，一定不在m_rowmap中，为false表示是改写记录，一定在m_rowmap中
			// fieldChangeFlags为该列信息是否改变，索引值为kColumn
			// 只有当拍序列的值改变了，
			if (!IsRecordNeeded(rid, record, size))
				return false;

			RecordKey key; key.rid = rid;
			m_record_list->Insert(key);
			return true;
		}


		int TableUser::CompareRecord(Table* table, const void* left, const void* right)
		{
			// 与TableSorter::CompareColumns对比，稍有不同
			// 递减递增排序来自m_sort_desc_flags
			// ColumnInfo中的m_dec其实也来自m_sort_desc_flags
            BASSERT(left && right && left != right);

			//kColumn col = table->GetKeyColumn();
			//const ColumnInfo& ci = table->GetColumnInfo(col);
			//int ret = ci.GetCompFunc()((const char*)left + ci.GetOffset(), (const char*)right + ci.GetOffset());
			//return  ret;

			for (int i = 0; i < (int)m_grid_columns.m_sort_columns.size(); i++)
			{
				kColumn col = m_grid_columns.m_sort_columns.at(i);
				const ColumnInfo& ci = table->GetColumnInfo(col);
				int ret = ci.GetCompFunc()((const char*)left + ci.GetOffset(), (const char*)right + ci.GetOffset());
				if (ret != 0)
					return m_grid_columns.m_sort_desc_flags.at(i) ? -ret : ret;
			}
			return  0;
		}
        void TableUser::UpdateIndex(const std::vector<INDEX>& indexes)
		{
			// 这里已经排好顺序,只需要放到末尾即可
			m_record_list->Clear();
			int count = indexes.size();
			m_record_list->BeginPush(count);
			for (int i = 0; i < count; i++)
			{
				RecordKey key;
				key.rid = indexes[i].rid;
				m_record_list->Push(key);
			}
			m_record_list->EndPush(false);
		}
		void TableUser::UpdateIndex(SortBuffer* sortBuffer)
		{
			// 这里已经排好顺序,只需要放到末尾即可
			m_record_list->Clear();
			int count = sortBuffer->GetRecordCount();
			m_record_list->BeginPush(count);
			for (int i = 0; i < count; i++)
			{
				RecordKey key;
				key.rid = sortBuffer->GetRecordId(i);
				m_record_list->Push(key);
			}
			m_record_list->EndPush(false);
		}
	}//namespace ht
}//namespace ss
